#include  "rtos_classes.h"

RTX:: RTX(){
	for( int i = 0; i < Num_Proc; i++ )
        {PCB_list[ i ] = NULL;}
        cur_proc=NULL;
        system_time=0;
        free_env_Q=NULL;
	//not for partial	ready_queue; //with 4 priority queues
	//not for partial	blocked_queue; //with 2 priority queues
	//send_trace_buffer[TraceBufferSize];
	//receive_trace_buffer[TraceBufferSize];
}

int RTX::initialization(initTable init_table){
	//init_MsgEn
        free_env_Q = new MsgEnvQ(Num_MsgEnv);
        //init_PCB
        PCB PCB_list[Num_Proc];
                for(int i=0;i<=Num_Proc;i++){
                    //put the values in init_table into according fields in PCBs
                    PCB_list[i]=new PCB;
                    PCB_list[i]->next=NULL;
                    PCB_list[i]->msgQ=NULL;
                    PCB_list[i]->pid=init_table[i].pid;
                    PCB_list[i]->priority=init_table[i].priority;
                    PCB_list[i]->status=init_table[i].status;
                    //	PCB_list[i]->stack=new int *  //not needed for partial
                    //	[init_table[i].stack_size],init_table[i].stack_size;  // not in partial
                    PCB_list[i]->address=(void(*)())init_table[i].start_address;
	}
        //setjmp, longjmp to start porcesses here
        //not for partial

 	 //current_process = procP PCB
 	 int cur_proc=PCB_list[ProcessP];
 	 //current_process->status = NEVER_BLK_PROC
 	 PCB_list[ProcessP]->status=NEVER_BLK_PROC;

}			 

PCB * RTX::search_PCB(int target_pid){
    PCB * temp_PCB;
    temp_PCB=PCB_list[0];
    while(temp_PCB!=0){
    if (temp_PCB->pid=target_pid)
    return temp_PCB;
    else
    temp_PCB=temp_PCB->next;
    }
    return 0;
}			 

void RTX::addTrace(MsgEnv*){
	  return;
}				 

void RTX::process_switch(){
	  /*
	  PCB *next_proc;
	  next_proc=ready_queue.dequeue();//make local next
	  process pointer pointing to the highest priority process on
	  ready Q;
	  next_proc->status=executing;
	  context_switch(next_proc);*/
	  return;
}

void RTX::context_switch(PCB * next){
	  /*if (setjmp(cur_porc->procContext)==0){
	  	  longjmp(next_proc->procContext, 1);
	  	  cur_proc=next_proc;//cur_process is point the new
	  	  process now
	  }*/
	  return;
}		 
void RTX::rpq_enqueue(PCB* newPcb){
	  //ready_queue.enqueue();	  
	  return -1;
}		 
PCB* RTX::rpq_dequeue(){
	  //return the PCB with the highest priority
	  //ready_queue.dequeue();
	  return -1;
}		 
				 



//the primitives!!	
int RTX::send_message(int dest_pid, MsgEnv *msg_envelope )
{//made some changes here, we only need one argument for this function since the envelope passed into the send message function will contain the target pid.
 //We need a way to get the PCB pointer from the pid. It should be easy because we know which process the message is going to be sent to
      *PCB dest_PCB;
      *msg_envelope->target_pid = dest_pid;
      dest_PCB=search_PCB(int dest_pid);//dest_PCB is a pointer to the destination process
      dest_PCB->msgQ.enqueue(msg_envelope)//put msg onto msg Q of dest_PCB
 	//if (dest_process_id.status == 3)//however, if destination process status=blocked on receive
 	//{
    //            dest_PCB.status=2//set status to ready
 	// 	rpq.enqueue (Msg_Env, dest_PCB);
    //           addTrace(Msg_Env);
    //    }
cout<<"msg received!";
return 1;
}


MsgEnv * RTX:: receive_message( )
{
 	*MsgEnv MsgEnv;
 	*MsgEnv temp;
        while (cur_proc->msgQ=NULL || cur_proc->status==5) {//if no msg to receive or status = 5(NO BLOCK RECEIVE)
                return NULL;
        //addtrace(MsgEnv*);//not in partial
        }
        temp=cur_proc->msgQ.dequeue(); 
        return temp;
}

int RTX:: send_console_chars(MsgEnv * message_envelope ){
//Used to display text on CRT

//Send MsgEnv pointer and process ID to CRT Iprocess
message_envelope->sender_pid=cur_proc;
message_envelope->target_pid=1;//CRT==1
message_envelope->type=4;//request_output

send_message(message_envelope);

//Force CRT i_proc to run once
CRT_iproc();

}

int RTX:: get_console_chars(MsgEnv * message_envelope ){
//Used to recieve input from user/KB
message_envelope->sender_pid=cur_proc;
message_envelope->target_pid=0; //KB Iproc
message_envelope->type=3;//request_input

//force Run KB i_process once
KB_iproc(cur_proc->pid);

}


/*		
int RTX::send_message( int dest_process_id, MsgEnv *msg_envelope ){
}
MsgEnv * RTX::receive_message( ){
}
MsgEnv * RTX::request_msg_env( ){
}
int RTX::release_msg_env ( MsgEnv * memory_block ){
}
int RTX::release_processor( ){
}
int RTX::request_process_status( MsgEnv * memory_block ){
}
int RTX::terminate( ){
}
int RTX::change_priority(int new_priority, int target_process_id){
}
int RTX::request_delay( int time_delay, int wakeup_code, MsgEnv *message_envelope ){
}
int RTX::send_console_chars(MsgEnv * message_envelope ){
}
int RTX::get_console_chars(MsgEnv * message_envelope ){
}
int RTX::get_trace_buffers( MsgEnv * message_envelope){
}
void CRT_iproc(){}
void KB_iproc(){}
process_P(){}*/
